<!doctype html>
<html lang="en-us">
    <head>
        <meta charset="utf-8">
        <title>ImTui Emscripten example</title>

        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>

        <link rel="shortcut icon" href="favicon.ico">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>

        <div>
            <pre id="screen" class="no-sel" contenteditable="true" unselectable="on" autocomplete='off' spellcheck='false' autocorrect='off'><span id="single-char"> </span></pre>
        </div>

        <div class="cell-version">
            <span>
                |
                Build time: <span class="nav-link">@GIT_DATE@</span> |
                Commit hash: <a class="nav-link" href="https://github.com/ggerganov/imtui/commit/@GIT_SHA1@">@GIT_SHA1@</a> |
                Commit subject: <span class="nav-link">@GIT_COMMIT_SUBJECT@</span> |
            </span>
        </div>
        <div class="cell-about">
            <a class="nav-link" href="https://github.com/ggerganov/imtui/tree/master/examples/emscripten0"><span class="d-none d-sm-inline">View on GitHub </span>
                <svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-mark-github" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
            </a>
        </div>

        <script type='text/javascript'>

            var screenX = -1;
            var screenY = -1;

            var charSizeX = document.getElementById('single-char').getBoundingClientRect().width;
            var charSizeY = document.getElementById('single-char').getBoundingClientRect().height;

            function toChar(event) {
                if (event.key.length == 1) {
                    return event.key.charCodeAt(0);
                }
                return event.keyCode;
            }

            function onkeyup(event) {
                Module._set_key_up(toChar(event));

                if (event.keyCode >= 112 && event.keyCode <= 123) {
                } else {
                    event.preventDefault();
                }
            }

            function onkeydown(event) {
                //console.log(event);
                Module._set_key_down(toChar(event));

                if (event.keyCode >= 112 && event.keyCode <= 123) {
                } else {
                    event.preventDefault();
                }
            }

            function onkeypress(event) {
                Module._set_key_press(toChar(event));

                if (event.keyCode >= 112 && event.keyCode <= 123) {
                } else {
                    event.preventDefault();
                }
            }

            function onpointermove(event) {
                var mouse_x = event.clientX/charSizeX;
                var mouse_y = event.clientY/charSizeY;

                Module._set_mouse_pos(mouse_x, mouse_y);

                event.preventDefault();
            };

            function onpointerdown(event) {
                var mouse_x = event.clientX/charSizeX;
                var mouse_y = event.clientY/charSizeY;

                Module._set_mouse_down(event.button, mouse_x, mouse_y);
            }

            function onpointerup(event) {
                var mouse_x = event.clientX/charSizeX;
                var mouse_y = event.clientY/charSizeY;

                Module._set_mouse_up(event.button, mouse_x, mouse_y);

                event.preventDefault();
            }

            function oncontextmenu(event) {
                event.preventDefault();
            }

            function onwheel(event) {
                let scale = 1.0;
                switch (event.deltaMode) {
                    case event.DOM_DELTA_PIXEL:
                        scale = 0.01;
                        break;
                    case event.DOM_DELTA_LINE:
                        scale = 0.2;
                        break;
                    case event.DOM_DELTA_PAGE:
                        scale = 1.0;
                        break;
                }

                var wheel_x =  event.deltaX * scale;
                var wheel_y = -event.deltaY * scale;

                Module._set_mouse_wheel(wheel_x, wheel_y);

                event.preventDefault();
            }

            function ontouch(event) {
                if (event.touches.length > 1) {
                    return;
                }

                var touches = event.changedTouches,
                    first = touches[0],
                    type = "";

                switch(event.type) {
                    case "touchstart": type = "mousedown"; break;
                    case "touchmove":  type = "mousemove"; break;
                    case "touchend":   type = "mouseup";   break;
                    default:           type = "mousemove";
                }

                // initMouseEvent(type, canBubble, cancelable, view, clickCount,
                //                screenX, screenY, clientX, clientY, ctrlKey,
                //                altKey, shiftKey, metaKey, button, relatedTarget);

                var simulatedEvent = document.createEvent("MouseEvent");
                simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);

                first.target.dispatchEvent(simulatedEvent);
                event.preventDefault();
            }

            function init() {
                var screen = document.getElementById('screen');

                screen.addEventListener('keyup', onkeyup, true);
                screen.addEventListener('keydown', onkeydown, true);
                screen.addEventListener('keypress', onkeypress, true);

                screen.addEventListener('pointermove', onpointermove);
                screen.addEventListener('mousemove', onpointermove);

                screen.addEventListener('pointerdown', onpointerdown);
                screen.addEventListener('mousedown', onpointerdown);

                screen.addEventListener('pointerup', onpointerup);
                screen.addEventListener('mouseup', onpointerup);

                screen.addEventListener('contextmenu', function(event) { oncontextmenu(event); });
                screen.addEventListener('wheel', onwheel, false);

                screen.addEventListener('touchstart', ontouch);
                screen.addEventListener('touchmove', ontouch);
                screen.addEventListener('touchend', ontouch);
                screen.addEventListener('touchcancel', ontouch);

                window.requestAnimationFrame(renderFrame);
            }

            var Module = {
                preRun: [],
                postRun: [(function () {
                    init();
                })
                ],
                print: (function() {
                    return function(text) {
                        text = Array.prototype.slice.call(arguments).join(' ');
                        console.log(text);
                    };
                })(),
                printErr: function(text) {
                    text = Array.prototype.slice.call(arguments).join(' ');
                    console.error(text);
                },
                setStatus: function(text) {
                    console.log("status: " + text);
                },
                monitorRunDependencies: function(left) {
                    // no run dependencies to log
                }
            };
            window.onerror = function() {
                console.log("onerror: " + event);
            };

            var bufferScreen = null;
            var bufferScreenMax = 0;

            var oldRow = {};

            function renderFrame() {
                var screen = document.getElementById('screen');

                var screenXNew = Math.floor(window.innerWidth/charSizeX - 1);
                var screenYNew = Math.floor(window.innerHeight/charSizeY - 2);

                if (screenXNew != screenX || screenYNew != screenY) {
                    if (screenYNew != screenY) {
                        oldRow = {}
                    }

                    screenX = screenXNew;
                    screenY = screenYNew;

                    screen.innerHTML = '';
                    for (var i = 0; i < screenY; ++i) {
                        screen.innerHTML += '<span id="r'+i+'"></span>';
                    }

                    Module._set_screen_size(screenX, screenY);

                    if (screenX*screenY > bufferScreenMax) {
                        if (bufferScreen != null) {
                            Module._free(bufferScreen);
                        }

                        bufferScreen = Module._malloc(3*screenX*screenY);
                        bufferScreenMax = screenX*screenY;
                    }
                }

                Module._render_frame();
                Module._get_screen(bufferScreen);

                var idx = 0;
                for (var y = 0; y < screenY; ++y) {
                    var curRow = '';
                    var prevf = -1;
                    var prevb = -1;
                    curRow += '<span class="cell f0 b0">';
                    for (var x = 0; x < screenX; ++x) {
                        var c = (Module.HEAPU8)[bufferScreen + idx]; ++idx;
                        var f = (Module.HEAPU8)[bufferScreen + idx]; ++idx;
                        var b = (Module.HEAPU8)[bufferScreen + idx]; ++idx;
                        if (c > 10 && c < 128) {
                            c = String.fromCharCode(c);
                        } else {
                            c = ' ';
                        }

                        if (prevf != f || prevb != b) {
                            curRow += '</span><span class="cell f'+f+' b'+b+'">';
                        }

                        curRow += c;

                        prevf = f;
                        prevb = b;
                    }
                    curRow +='</span>\n';

                    if (curRow != oldRow[y]) {
                        oldRow[y] = curRow;
                        document.getElementById('r'+y).innerHTML = curRow;
                    }
                }

                window.requestAnimationFrame(renderFrame);
            }

        </script>
        <script async type="text/javascript" src="@TARGET@.js"></script>
    </body>
</html>
